﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Kokomo.Environment;
using System.Reflection;
using System.Collections;
using System.Windows.Data;
using System.ComponentModel;
using System.Windows.Input;

namespace Kokomo.PeInspector.Reflection
{
	[ViewType(typeof(NamespaceTypesView))]
	class NamespaceTypesViewModel : SearchViewModel<TypeItem>
	{
		public NamespaceScope NamespaceScope { get; private set; }
		public IMetadataHost Host { get; private set; }

		public NamespaceTypesViewModel(
			NamespaceScope namespaceScope,
			IMetadataHost host,
			ICommand navigateToCommand
			)
		{
			if (namespaceScope == null) throw new ArgumentNullException("namespaceScope");
			if (host == null) throw new ArgumentNullException("host");

			this.NamespaceScope = namespaceScope;
			this.Host = host;
			this.NavigateToCommand = navigateToCommand;

			this.PopulateItems();
		}

		public ICommand NavigateToCommand { get; private set; }

		#region Members
		private IEnumerable<TypeItem> _typeItems;

		public bool GroupsTypesByKind
		{
			get { return AssemblyAnalyzerEditor.ViewSettings.GroupTypeMembers; }
			set
			{
				AssemblyAnalyzerEditor.ViewSettings.GroupTypeMembers = value;
				this.OnGroupsTypesByKindChanged();
			}
		}
		protected virtual void OnGroupsTypesByKindChanged()
		{
			this.ApplyGrouping(this.Results);
			this.OnPropertyChanged("GroupsTypesByKind");
		}

		private void PopulateItems()
		{
			Type[] types = this.NamespaceScope.Types.OrderBy(m => m.Name).ToArray();

			List<TypeItem> items = new List<TypeItem>();
			foreach (var type in types)
			{
				TypeItem item = new TypeItem(type, MemberViewInfo.GetMemberViewInfo(type));
				items.Add(item);
			}

			this._typeItems = items;
		}
		#endregion

		protected override IEnumerable<TypeItem> OnSearchAsync(string searchTerm, int searchVersion)
		{
			if (string.IsNullOrEmpty(searchTerm)) return this._typeItems;

			var items = this._typeItems.Where(t => t.MemberName.Contains(searchTerm, StringComparison.InvariantCultureIgnoreCase)).ToArray();
			return items;
		}
		protected override void OnResultsChanging(IEnumerable<TypeItem> results)
		{
			base.OnResultsChanging(results);

			this.ApplyGrouping(results);
		}
		private void ApplyGrouping(IEnumerable<TypeItem> results)
		{
			ICollectionView view = CollectionViewSource.GetDefaultView(results);
			view.GroupDescriptions.Clear();
			if (this.GroupsTypesByKind)
			{
				view.GroupDescriptions.Add(new PropertyGroupDescription("Kind"));
			}
		}
	}
}
